"""
版本说明：当前文件主要增加了根据数据库参数表中math_open_lots 参数是否开启，来决定是否根据算法计算开仓手数的功能，
        也就是说，每次可以不止下单1手。而是根据资金量、保证金等条件来计算下单开仓量。

和上一版本区别：
    上一版本文件名为：auto_stp10_stable04_06_codebuddy_算法修正版_01.py
    把操盘线trading_line和空头线short_line的计算过程移动到了主程序内部，而上一版本是在外部文件中以函数形式计算，然后以模块形式导入主程序，在主程序中调用的。
"""

import time, os
from threading import Thread, Lock
from dbutils.pooled_db import PooledDB
import pymysql
import numpy as np
import pandas as pd
from tqsdk import TqApi, TqAuth, TqKq
from rich.console import Console
from rich.theme import Theme
from MyTT import REF, EMA, SUM
import logging

# 数据库配置 - 仅使用MySQL
USE_MYSQL = True


# 定义控制台输出，更明亮显眼颜色主题
custom_theme = Theme({
    "info": "bright_cyan",
    "warning": "bright_yellow",
    "error": "bright_red",
    "success": "bright_green",
    "trade": "bold bright_magenta"
})
console = Console(theme=custom_theme)

# 添加交互式进度条
# with console.status("正在连接数据库...", spinner="dots") as status:
#     # 模拟数据处理延迟
#     #import time
#     time.sleep(5)
    
# print("测试，Line:44")

# 根据配置选择数据库连接池
db = None
try:
    # MySQL数据库连接池
    db = PooledDB(
        creator=pymysql,
        host='172.28.196.123',  # 请替换为您的MySQL服务器地址
        user='remote_admin',    # 请替换为您的MySQL用户名
        password='Admin@szlwy68',  # 请替换为您的MySQL密码
        database='trade_monitor', # 请替换为您的MySQL数据库名
        port=3306,              # MySQL默认端口
        maxconnections=5,
        mincached=2,
        maxcached=3,
        maxshared=3,
        blocking=True,
        autocommit=True,        # 添加自动提交选项
        charset='utf8mb4',      # 指定字符集
        connect_timeout=3,      # 连接超时时间，单位秒
        #read_timeout=3          # 读取超时时间，单位秒
    )
    console.print("成功连接到MySQL数据库", style="success")
except Exception as e:
    console.print(f"无法连接到MySQL数据库: {str(e)}", style="error")
    logging.error(f"数据库连接失败: {str(e)}", exc_info=True)
    exit(1)


# 配置日志记录
logging.basicConfig(
    filename='trading_log.log',
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

# 改变控制台背景色和字体色，控制台窗口大小
# os.system("COLOR 02")
# os.system("mode con cols=150 lines=50")

######################################## 定义全局变量########################################
symbols = []
api = None
threads = []

# 定义开仓资金比例（占可用资金的百分比）
POSITION_FUND_RATIO = 0.2  # 20%，可以根据需要调整
######################################## 定义函数########################################
def insert_trade_orders(order_id, symbol, direction, offset, volume, price, reason):
    """
    将委托信息记录到 trade_orders 表
    :param order_id: 订单ID
    :param symbol: 交易品种
    :param direction: 交易方向 (BUY/SELL)
    :param offset: 开平标志 (OPEN/CLOSE/CLOSETODAY)
    :param volume: 交易手数
    :param price: 价格
    :param reason: 交易原因
    """
    try:
        global USE_MYSQL
        timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
        
        # MySQL连接方式
        conn = db.connection()
        cursor = conn.cursor()
        cursor.execute(
            "INSERT INTO trade_orders (order_id, product_name, direction, offset, volume, price, reason, timestamp) "
            "VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
            (order_id, symbol, direction, offset, volume, price, reason, timestamp)
        )
        conn.commit()
        cursor.close()
        conn.close()
        
        logging.info(f"委托信息已记录: 订单ID={order_id}, 品种={symbol}, 方向={direction}, 开平={offset}, 手数={volume}, 价格={price}, 原因={reason}")
    except Exception as e:
        console.print(f"记录委托信息时出错: {e}", style="error")
        logging.error(f"记录委托信息时出错: {e}", exc_info=True)
        
def on_order_status_changed(order, symbol, volume, order_id, limit_price, direction, offset, reason):
    """
    订单状态变更回调函数
    :param order: 订单对象
    :param symbol: 交易品种
    :param volume: 交易手数
    :param order_id: 订单ID
    :param limit_price: 限价
    :param direction: 交易方向 (BUY/SELL)
    :param offset: 开平标志 (OPEN/CLOSE/CLOSETODAY)
    :param reason: 交易原因
    """
    try:
        # 记录订单状态变更到日志
        logging.info(
            f"订单状态变更: 品种={symbol}, 订单ID={order_id}, 方向={direction}, 开平={offset}, 手数={volume}, 价格={limit_price}, 原因={reason}"
        )
        
        # 更新trade_orders表中的订单状态
        try:
            conn = db.connection()
            cursor = conn.cursor()
            cursor.execute(
                "UPDATE trade_orders SET status = %s WHERE order_id = %s",
                (order.status, order_id)
            )
            conn.commit()
            cursor.close()
            conn.close()
            console.print(f"已更新订单 {order_id} 状态为 {order.status}", style="success")
        except Exception as e:
            console.print(f"更新订单状态到trade_orders表失败: {e}", style="error")
            logging.error(f"更新订单状态到trade_orders表失败: {e}", exc_info=True)
        
        # 根据订单状态执行逻辑
        if order.status == "FINISHED":
            console.print(f"订单 {order_id} 已成交", style="success")
            # 更新trade_records表记录成交信息
            try:
                insert_trade_record(
                    symbol=symbol,
                    direction=direction,
                    offset=offset,
                    volume=volume,
                    price=getattr(order, 'price', None) or limit_price,
                    reason=f"订单成交: {reason}"
                )
                console.print(f"已更新订单 {order_id} 成交记录到trade_records表", style="success")
            except Exception as e:
                console.print(f"更新成交记录到trade_records表失败: {e}", style="error")
                logging.error(f"更新成交记录到trade_records表失败: {e}", exc_info=True)
        elif order.status == "CANCELED":
            console.print(f"订单 {order_id} 已撤单", style="warning")
            # 可以在这里添加撤单后的逻辑
        else:
            console.print(f"订单 {order_id} 状态更新为: {order.status}", style="info")
    except Exception as e:
        console.print(f"处理订单状态变更时出错: {e}", style="error")
        logging.error(f"处理订单状态变更时出错: {e}", exc_info=True)

# 新增函数：获取 config 表所有配置项
def get_all_configs():
    """
    从 config 表中获取所有配置项，以字典形式返回
    :return: 包含所有配置项的字典
    """
    try:
        global USE_MYSQL
        # MySQL连接方式
        conn = db.connection()
        cursor = conn.cursor()
        cursor.execute("SELECT `key`, `value` FROM config")
        results = cursor.fetchall()
        cursor.close()
        conn.close()
        
        # 创建配置字典
        config_dict = dict(results)
        
        # 不动态修改USE_MYSQL全局变量，避免连接池不匹配问题
        # 只返回配置值，让调用者决定如何使用
        
        return config_dict
    except Exception as e:
        console.print(f"从数据库获取所有配置项时出错: {e}", style="error")
        logging.error(f"从数据库获取所有配置项时出错: {e}", exc_info=True)
        return {}

def get_symbols():
    global USE_MYSQL
    try:
        # MySQL连接方式
        conn = db.connection()
        cursor = conn.cursor()
        # 查询品种代码和 mtp 字段
        cursor.execute("SELECT exchange_code FROM products WHERE is_monitored=1")
        products = cursor.fetchall()
        cursor.close()
        conn.close()
        
        # 返回包含品种代码和 mtp 值的列表
        return [product[0] for product in products]
    except Exception as e:
        console.print(f"从数据库获取监控品种时出错: {e}", style="error")
        logging.error(f"从数据库获取监控品种时出错: {e}", exc_info=True)
        return []

# 新增函数：记录交易到数据库
def insert_trade_orders(symbol, direction, offset, volume, price, reason, order_id=None):
    global USE_MYSQL
    try:
        timestamp = time.strftime('%Y-%m-%d %H:%M:%S')       
        # MySQL连接方式
        conn = db.connection()
        cursor = conn.cursor()

        # 使用参数化查询防止SQL注入 (MySQL使用%s作为占位符)
        if order_id:
            sql = """
            INSERT INTO trade_records 
            (product_name, direction, offset, volume, price, reason, timestamp, order_id) 
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
            """
            cursor.execute(sql, (symbol, direction, offset, volume, price, reason, timestamp, order_id))
        else:
            sql = """
            INSERT INTO trade_records 
            (product_name, direction, offset, volume, price, reason, timestamp) 
            VALUES (%s, %s, %s, %s, %s, %s, %s)
            """
            cursor.execute(sql, (symbol, direction, offset, volume, price, reason, timestamp))

        conn.commit()
        cursor.close()
        conn.close()
            
        console.print(f"成功记录交易: {symbol} {direction} {offset} {volume}手 价格{price}", style="success")
    except Exception as e:
        console.print(f"记录交易到数据库时出错: {e}", style="error")
        logging.error(f"记录交易到数据库时出错: {e}", exc_info=True)

def check_position_and_orders(api, symbol):
    """
    检查指定品种是否有未完成订单或已有持仓
    :param api: TqSdk API对象
    :param symbol: 交易品种
    :return: (bool, str) - (是否可以开仓, 原因)
    """
    try:
        # 获取配置信息
        configs = get_all_configs()
        math_open_lots = configs.get('math_open_lots', 'off').lower() == 'on'
        
        # 检查持仓情况 - 如果启用了math_open_lots，则允许在已有持仓的情况下继续开仓
        position = api.get_position(symbol)
        if not math_open_lots:
            if hasattr(position, 'pos_long') and position.pos_long > 0:
                return False, f"{symbol}已有{position.pos_long}手多仓持仓"
            if hasattr(position, 'pos_short') and position.pos_short > 0:
                return False, f"{symbol}已有{position.pos_short}手空仓持仓"
        
        # 检查未完成订单（仅检查开仓单）
        orders = api.get_order()
        if hasattr(orders, 'list') and callable(orders.list):
            order_list = orders.list()
        elif isinstance(orders, list):
            order_list = orders
        elif isinstance(orders, dict):
            order_list = list(orders.values())
        else:
            order_list = list(orders)
        
        for order in order_list:
            if hasattr(order, 'symbol') and hasattr(order, 'status') and hasattr(order, 'offset'):
                order_symbol = order.symbol
                order_status = order.status
                order_offset = order.offset
            elif hasattr(order, 'get'):
                order_symbol = order.get('symbol')
                order_status = order.get('status')
                order_offset = order.get('offset')
            else:
                order_symbol = order['symbol'] if 'symbol' in order else None
                order_status = order['status'] if 'status' in order else None
                order_offset = order['offset'] if 'offset' in order else None
            
            if (order_symbol == symbol and 
                order_status not in ('FINISHED', 'CANCELED') and 
                order_offset == 'OPEN'):
                return False, f"{symbol}有未完成开仓订单"
        
        return True, "无未完成订单，可以开仓"
    except Exception as e:
        logging.error(f"检查{symbol}持仓和订单时出错: {str(e)}", exc_info=True)
        return False, f"检查出错: {str(e)}"

def stop_loss(symbol):
    global USE_MYSQL
    # 在每个线程中创建独立的数据库连接，而不是使用连接池
    api = TqApi(account=TqKq(), auth=TqAuth("cps168", "alibaba"))
    while True:
        deadline = time.time() + 2
        api.wait_update(deadline=deadline)

        #########################查询数据库中设置信息##########################################################
        try:
            # MySQL连接方式
            conn = db.connection()
            cursor = conn.cursor()
            cursor.execute("SELECT limit_stoploss,mtp,dks FROM products WHERE exchange_code=%s AND is_monitored=1", (symbol,))
            result = cursor.fetchone()
            cursor.close()
            conn.close()

            if result is None:
                stop_loss_limit = 3000  # 限额止损
                mtp = 5  # 移动止盈止损周期
                dks = "双向"  # 开仓方向
            else:
                stop_loss_limit = int(result[0])  # 限额止损
                # 处理 mtp 数据，确保其为有效的整数
                try:
                    mtp = int(result[1])
                    # 限制 mtp 在合理范围内，例如 1 到 3600
                    mtp = max(1, min(mtp, 3600))
                except (ValueError, TypeError):
                    console.print(f"从数据库获取 {symbol} 的 mtp 值无效，使用默认值", style="warning")
                    mtp = 5
                dks = str(result[2])  # 开仓方向
            
        except Exception as e:
            console.print(f"从数据库获取 {symbol} 止损限额时出错: {e}", style="error")
            logging.error(f"从数据库获取 {symbol} 止损限额时出错: {e}", exc_info=True)
            return

        #########################获取数据逻辑#######################################################################
        # 获取 k 线数据
        try:
            klines = api.get_kline_serial(symbol, 60 * mtp, data_length=300)
            quote = api.get_quote(symbol)
            position = api.get_position(symbol)
            orders = api.get_order(symbol)
            console.print(f"{time.strftime('%X')} 开始处理 {symbol}", style="warning")
        except Exception as e:
            if "non-existent instrument" in str(e):
                console.print(f"获取 {symbol} 数据时出错，合约可能不存在，请检查合约代码: {e}", style="error")
            else:
                console.print(f"获取 {symbol} 数据时出错: {e}", style="error")
            return


        # 撤销所有未成交订单
        for order_id, order in orders.items():
            if hasattr(order, 'status') and order.status == 'ALIVE':
                api.cancel_order(order)

        console.print(f"{time.strftime('%X')} 开始检查{symbol}止损条件", style="warning")
        try:
        #########################处理各种类型的止损逻辑##########################################################
            if api.is_changing(quote):
                # ***************************************限额止损检查***************************************
                if position.pos_short > 0:
                    short_loss_per_hand = (position.open_price_short - quote.last_price) * quote.volume_multiple 
                    if short_loss_per_hand > stop_loss_limit:
                        if symbol.startswith('SHFE'):
                            if position.pos_short_today > 0:
                                limit_price = quote.ask_price1 + 2 * quote.price_tick
                                volume = position.pos_short_today
                                if volume > 0:
                                    try:
                                        order_id = api.insert_order(
                                                symbol=symbol,
                                                direction="BUY",
                                                offset="CLOSETODAY",
                                                volume=volume,
                                                limit_price=limit_price
                                            )
                                        console.print(
                                        f"{time.strftime('%X')} 平SHFE{symbol}今空仓(限额止损): 手数: {volume}",
                                        style="trade"
                                        )
                                        # 仅保留下单信息日志
                                        logging.info(
                                            f"平SHFE{symbol}今空仓(限额止损): 手数: {volume}, 平仓价格: {limit_price}"
                                        )
                                        insert_trade_orders(symbol, "BUY", "CLOSETODAY", volume, limit_price, "限额止损")
                                        # 平仓后立即更新持仓信息，以便后续开仓检查
                                    except Exception as e:
                                        console.print(f"平SHFE{symbol}今空仓(限额止损)时出错: {e}", style="error")
                                        logging.error(f"平SHFE{symbol}今空仓(限额止损)时出错: {e}", exc_info=True)
                                        return

                                    api.wait_update()
                                    
                            if position.pos_short_his > 0:
                                limit_price = quote.ask_price1 + 2 * quote.price_tick
                                volume = position.pos_short_his
                                if volume > 0:
                                    try:
                                        order_id = api.insert_order(
                                                symbol=symbol,
                                                direction="CLOSE",
                                                volume=volume,
                                                limit_price=limit_price
                                            )
                                        # 记录委托单到数据库
                                        try:
                                            insert_trade_orders(
                                                order_id=order_id,
                                                symbol=symbol,
                                                direction="BUY",
                                                offset="CLOSE",
                                                volume=volume,
                                                price=limit_price,
                                                status="ALIVE",
                                                remark="限额止损"
                                            )
                                        except Exception as e:
                                            logging.error(f"记录委托单失败: {e}")
                                        
                                        console.print(
                                            f"{time.strftime('%X')} 平SHFE{symbol}昨空仓(限额止损): 手数: {volume}",
                                            style="trade"
                                        )
                                        # 仅保留下单信息日志
                                        logging.info(
                                            f"平SHFE{symbol}昨空仓(限额止损): 手数: {volume}, 平仓价格: {limit_price}"
                                        )
                                    except Exception as e:
                                        console.print(f"平{symbol}昨空仓(限额止损)时出错: {e}", style="error")
                                        logging.error(f"平{symbol}昨空仓(限额止损)时出错: {e}", exc_info=True)
                                        return

                                    
                                    # 平仓后立即更新持仓信息，以便后续开仓检查
                                    api.wait_update()
                        #非上海交易所
                        else:
                            if position.pos_short > 0:
                                limit_price = quote.ask_price1 + 2 * quote.price_tick
                                volume = position.pos_short
                                if volume > 0:
                                    try:
                                        order_id = api.insert_order(
                                            symbol=symbol,
                                            direction="BUY",
                                            offset="CLOSE",
                                            volume=volume,
                                            limit_price=limit_price
                                        )
                                        # 记录委托单到数据库
                                        try:
                                            insert_trade_orders(
                                                order_id=order_id,
                                                symbol=symbol,
                                                direction="BUY",
                                                offset="CLOSE",
                                                volume=volume,
                                                price=limit_price,
                                                status="ALIVE",
                                                remark="限额止损"
                                            )
                                        except Exception as e:
                                            logging.error(f"记录委托单失败: {e}")
                                        
                                        console.print(
                                                f"{time.strftime('%X')} 平{symbol}空仓(限额止损): 手数: {volume}, 订单ID: {order_id}",
                                                style="trade"
                                            )
                                            # 仅保留下单信息日志
                                        logging.info(
                                                f"平{symbol}空仓(限额止损): 手数: {volume}, 平仓价格: {limit_price}, 订单ID: {order_id}"
                                            )
                                        
                                        # 注册订单状态变更回调
                                        close_order = order_id
                                        safe_close_id = (close_order if isinstance(close_order, str) else getattr(close_order, 'order_id', None))
                                        if isinstance(safe_close_id, int):
                                            safe_close_id = str(safe_close_id)
                                        api.get_order(safe_close_id, lambda o: on_order_status_changed(
                                            o, symbol, volume, safe_close_id, limit_price, "BUY", "CLOSE", "限额止损"
                                        ))                                        
                                        # 平仓后立即更新持仓信息，以便后续开仓检查
                                        api.wait_update()     
                                    except Exception as e:
                                        console.print(f"平{symbol}空仓(限额止损)时出错: {e}", style="error")
                                        logging.error(f"平{symbol}空仓(限额止损)时出错: {e}", exc_info=True)
                                        return


                if position.pos_long > 0:
                    long_loss_per_hand = (quote.last_price - position.open_price_long) * quote.volume_multiple 
                    if long_loss_per_hand > stop_loss_limit:
                        if symbol.startswith('SHFE'):
                            if position.pos_long_today > 0:
                                limit_price = quote.bid_price1 - 2 * quote.price_tick
                                volume = position.pos_long_today
                                if volume > 0:
                                    order_id = api.insert_order(
                                        symbol=symbol,
                                        direction="SELL",
                                        offset="CLOSETODAY",
                                        volume=volume,
                                        limit_price=limit_price
                                    )
                                    console.print(
                                        f"{time.strftime('%X')} 平SHFE{symbol}今多仓(限额止损): 手数: {volume}, 订单ID: {order_id}",
                                        style="trade"
                                    )
                                    # 仅保留下单信息日志
                                    logging.info(
                                        f"平SHFE{symbol}今多仓(限额止损): 手数: {volume}, 平仓价格: {limit_price}, 订单ID: {order_id}"
                                    )
                                    
                                    # 注册订单状态变更回调
                                    api.get_order(order_id, lambda o: on_order_status_changed(
                                        o, symbol, volume, order_id, limit_price, "SELL", "CLOSETODAY", "限额止损"
                                    ))
                                    
                                    # 平仓后立即更新持仓信息，以便后续开仓检查
                                    api.wait_update()
                            if position.pos_long_his > 0:
                                limit_price = quote.bid_price1 - 2 * quote.price_tick
                                volume = position.pos_long_his
                                if volume > 0:
                                    order_id = api.insert_order(
                                        symbol=symbol,
                                        direction="SELL",
                                        offset="CLOSE",
                                        volume=volume,
                                        limit_price=limit_price
                                    )
                                    # 记录委托单到数据库
                                    try:
                                        insert_trade_orders(
                                            order_id=order_id,
                                            symbol=symbol,
                                            direction="SELL",
                                            offset="CLOSE",
                                            volume=volume,
                                            price=limit_price,
                                            status="ALIVE",
                                            remark="限额止损"
                                        )
                                    except Exception as e:
                                        logging.error(f"记录委托单失败: {e}")
                                    
                                    console.print(
                                        f"{time.strftime('%X')} 平SHFE{symbol}昨多仓(限额止损): 手数: {volume}, 订单ID: {order_id}",
                                        style="trade"
                                    )
                                    # 仅保留下单信息日志
                                    logging.info(
                                        f"平SHFE{symbol}昨多仓(限额止损): 手数: {volume}, 平仓价格: {limit_price}, 订单ID: {order_id}"
                                    )
                                    
                                    # 注册订单状态变更回调
                                    api.get_order(order_id, lambda o: on_order_status_changed(
                                        o, symbol, volume, order_id, limit_price, "SELL", "CLOSE", "上交所品种限额止损"
                                    ))
                                    
                                    # 平仓后立即更新持仓信息，以便后续开仓检查
                                    api.wait_update()

                        else:
                            if position.pos_long > 0:
                                limit_price = quote.bid_price1 - 2 * quote.price_tick
                                volume = position.pos_long
                                if volume > 0:
                                    order_id = api.insert_order(
                                        symbol=symbol,
                                        direction="SELL",
                                        offset="CLOSE",
                                        volume=volume,
                                        limit_price=limit_price
                                    )
                                    # 记录委托单到数据库
                                    try:
                                        insert_trade_orders(
                                            order_id=order_id,
                                            symbol=symbol,
                                            direction="SELL",
                                            offset="CLOSE",
                                            volume=volume,
                                            price=limit_price,
                                            status="ALIVE",
                                            remark="限额止损"
                                        )
                                    except Exception as e:
                                        logging.error(f"记录委托单失败: {e}")
                                    
                                    console.print(
                                        f"{time.strftime('%X')} 平{symbol}多仓(限额止损): 手数: {volume}, 订单ID: {order_id}",
                                        style="trade"
                                    )
                                    # 仅保留下单信息日志
                                    logging.info(
                                        f"平{symbol}多仓(限额止损): 手数: {volume}, 平仓价格: {limit_price}, 订单ID: {order_id}"
                                    )
                                    
                                    # 注册订单状态变更回调
                                    api.get_order(order_id, lambda o: on_order_status_changed(
                                        o, symbol, volume, order_id, limit_price, "SELL", "CLOSE", "限额止损"
                                    ))
                                    
                                    # 平仓后立即更新持仓信息，以便后续开仓检查
                                    api.wait_update()

                # ***************************************趋势追踪止损检查***************************************
                #######################################################################################################
                """
                算法部分：
                计算博易大师技术指标，包含Q值、操盘线和空头线
                """
                close = klines.close
                open_price = klines.open
                high = klines.high
                low = klines.low
                
                # 计算Q值
                Q = (3*close + low + open_price + high) / 6
                Q = pd.Series(Q)
                
                # 手动实现 REF 函数
                def ref(series, n=1):
                    return series.shift(n)
                
                # 计算操盘线（26期Q值加权平均）
                terms = [
                    26 * Q,
                    25 * ref(Q, 1),
                    24 * ref(Q, 2),
                    23 * ref(Q, 3),
                    22 * ref(Q, 4),
                    21 * ref(Q, 5),
                    20 * ref(Q, 6),
                    19 * ref(Q, 7),
                    18 * ref(Q, 8),
                    17 * ref(Q, 9),
                    16 * ref(Q, 10),
                    15 * ref(Q, 11),
                    14 * ref(Q, 12),
                    13 * ref(Q, 13),
                    12 * ref(Q, 14),
                    11 * ref(Q, 15),
                    10 * ref(Q, 16),
                    9 * ref(Q, 17),
                    8 * ref(Q, 18),
                    7 * ref(Q, 19),
                    6 * ref(Q, 20),
                    5 * ref(Q, 21),
                    4 * ref(Q, 22),
                    3 * ref(Q, 23),
                    2 * ref(Q, 24),
                    ref(Q, 25)
                ]
                trading_line = pd.Series(sum(terms) / 351)
                
                # 手动实现 EMA 函数
                def ema(series, n=10):
                    return series.ewm(span=n, adjust=False).mean()
                
                # 计算空头线（操盘线的7期EMA）
                short_line = ema(trading_line, 7)               

                #logging.info(f"Symbol: {symbol}, Trading Line[-2]: {trading_line[-2]}, Short Line[-2]: {short_line[-2]}")
                console.print(f"条件值是：trading_line: {trading_line.iloc[-2]}, short_line: {short_line.iloc[-2]}",style="trade")
                #######################################################################################################
                # 确保数据长度足够，避免索引越界
                if len(trading_line) >= 3 and len(short_line) >= 3:
                    # 处理空单 - 添加标记以便平仓后可以立即检查开仓条件
                    position_changed = False
                    if trading_line.iloc[-2] > short_line.iloc[-2]:
                        if symbol.startswith('SHFE'):
                            if position.pos_short_today > 0:
                                limit_price = quote.ask_price1 + 2 * quote.price_tick
                                order_id = api.insert_order(
                                    symbol=symbol,
                                    direction="BUY",
                                    offset="CLOSETODAY",
                                    volume=position.pos_short_today,
                                    limit_price=limit_price
                                )
                                insert_trade_orders(order_id, symbol, "BUY", "CLOSETODAY", position.pos_short_today, limit_price, "均线追踪止损")
                                console.print(
                                    f"{time.strftime('%X')} 平SHFE{symbol}今空仓(均线追踪止损): 手数: {position.pos_short_today}, 订单ID: {order_id}",
                                    style="trade"
                                )
                                logging.info(
                                    f"平SHFE{symbol}今空仓(均线追踪止损): 手数: {position.pos_short_today}, 平仓价格: {limit_price}, 订单ID: {order_id}"
                                )
                                
                                # 注册订单状态变更回调
                                api.get_order(order_id, lambda o: on_order_status_changed(
                                    o, symbol, position.pos_short_today, order_id, limit_price, "BUY", "CLOSETODAY", "均线追踪止损"
                                ))
                                
                                # 平仓后立即更新持仓信息，以便后续开仓检查
                                api.wait_update()
                                position_changed = True
                            if position.pos_short_his > 0:
                                limit_price = quote.ask_price1 + 2 * quote.price_tick
                                order_id = api.insert_order(
                                    symbol=symbol,
                                    direction="BUY",
                                    offset="CLOSE",
                                    volume=position.pos_short_his,
                                    limit_price=limit_price
                                )
                                insert_trade_orders(order_id, symbol, "BUY", "CLOSE", position.pos_short_his, limit_price, "均线追踪止损")
                                console.print(
                                    f"{time.strftime('%X')} 平SHFE{symbol}昨空仓(均线追踪止损): 手数: {position.pos_short_his}, 订单ID: {order_id}",
                                    style="trade"
                                )
                                logging.info(
                                    f"平SHFE{symbol}昨空仓(均线追踪止损): 手数: {position.pos_short_his}, 平仓价格: {limit_price}, 订单ID: {order_id}"
                                )
                                
                                # 注册订单状态变更回调
                                api.get_order(order_id, lambda o: on_order_status_changed(
                                    o, symbol, position.pos_short_his, order_id, limit_price, "BUY", "CLOSE", "均线追踪止损"
                                ))
                                
                                # 平仓后立即更新持仓信息，以便后续开仓检查
                                api.wait_update()
                        else:
                            limit_price = quote.ask_price1 + 2 * quote.price_tick
                            if position.pos_short > 0:
                                order_id = api.insert_order(
                                    symbol=symbol,
                                    direction="BUY",
                                    offset="CLOSE",
                                    volume=position.pos_short,
                                    limit_price=limit_price
                                )
                                console.print(
                                    f"{time.strftime('%X')} 平{symbol}空仓(均线追踪止损): 手数: {position.pos_short}, 订单ID: {order_id}",
                                    style="trade"
                                )
                                logging.info(
                                    f"平{symbol}空仓(均线追踪止损): 手数: {position.pos_short}, 平仓价格: {limit_price}, 订单ID: {order_id}"
                                )
                                
                                # 注册订单状态变更回调
                                api.get_order(order_id, lambda o: on_order_status_changed(
                                    o, symbol, position.pos_short, order_id, limit_price, "BUY", "CLOSE", "均线追踪止损"
                                ))
                                
                                # 平仓后立即更新持仓信息，以便后续开仓检查
                                api.wait_update()


                    # 处理多单 - 添加标记以便平仓后可以立即检查开仓条件
                    position_changed = False
                    if trading_line.iloc[-2] < short_line.iloc[-2]:
                        if symbol.startswith('SHFE'):
                            if position.pos_long_today > 0:
                                limit_price = quote.bid_price1 - 2 * quote.price_tick
                                order_id = api.insert_order(
                                    symbol=symbol,
                                    direction="SELL",
                                    offset="CLOSETODAY",
                                    volume=position.pos_long_today,
                                    limit_price=limit_price
                                )
                                console.print(
                                    f"{time.strftime('%X')} 平SHFE{symbol}今多仓(均线追踪止损): 手数: {position.pos_long_today}, 订单ID: {order_id}",
                                    style="trade"
                                )
                                logging.info(
                                    f"平SHFE{symbol}今多仓(均线追踪止损): 手数: {position.pos_long_today}, 平仓价格: {limit_price}, 订单ID: {order_id}"
                                )
                                
                                # 注册订单状态变更回调
                                api.get_order(order_id, lambda o: on_order_status_changed(
                                    o, symbol, position.pos_long_today, order_id, limit_price, "SELL", "CLOSETODAY", "均线追踪止损"
                                ))
                                
                                # 平仓后立即更新持仓信息，以便后续开仓检查
                                api.wait_update()
                                position_changed = True
                            if position.pos_long_his > 0:
                                limit_price = quote.bid_price1 - 2 * quote.price_tick
                                volume = position.pos_long_his
                                if volume > 0:
                                    order_id = api.insert_order(
                                        symbol=symbol,
                                        direction="SELL",
                                        offset="CLOSE",
                                        volume=volume,
                                        limit_price=limit_price
                                    )
                                    console.print(
                                        f"{time.strftime('%X')} 平SHFE{symbol}昨多仓(均线追踪止损): 手数: {volume}, 订单ID: {order_id}",
                                        style="trade"
                                    )
                                    # 仅保留下单信息日志
                                    logging.info(
                                        f"平SHFE{symbol}昨多仓(均线追踪止损): 手数: {volume}, 平仓价格: {limit_price}, 订单ID: {order_id}"
                                    )
                                    
                                    # 注册订单状态变更回调
                                    api.get_order(order_id, lambda o: on_order_status_changed(
                                        o, symbol, volume, order_id, limit_price, "SELL", "CLOSE", "均线追踪止损"
                                    ))
                                    
                                    # 平仓后立即更新持仓信息，以便后续开仓检查
                                    api.wait_update()
                        else:
                            if position.pos_long>0:
                                limit_price = quote.bid_price1 - 2 * quote.price_tick
                                order_id = api.insert_order(
                                    symbol=symbol,
                                    direction="SELL",
                                    offset="CLOSE",
                                    volume=position.pos_long,
                                    limit_price=limit_price
                                )
                                console.print(
                                    f"{time.strftime('%X')} 平{symbol}多仓(均线追踪止损): 手数: {position.pos_long}, 订单ID: {order_id}",
                                    style="trade"
                                )
                                logging.info(
                                    f"平{symbol}多仓(均线追踪止损): 手数: {position.pos_long}, 平仓价格: {limit_price}, 订单ID: {order_id}"
                                )
                                
                                # 注册订单状态变更回调
                                api.get_order(order_id, lambda o: on_order_status_changed(
                                    o, symbol, position.pos_long, order_id, limit_price, "SELL", "CLOSE", "均线追踪止损"
                                ))
                                
                                # 平仓后立即更新持仓信息，以便后续开仓检查
                                api.wait_update()
                                position_changed = True
        except Exception as e:
            console.print(f"处理 {symbol} 止损逻辑时出错: {e}", style="error")
            
        # 如果在止损过程中有持仓变化，立即检查是否可以开仓
        if 'position_changed' in locals() and position_changed:
            console.print(f"{time.strftime('%X')} 检测到{symbol}持仓变化，立即检查开仓条件", style="warning")
            # 更新持仓信息
            position = api.get_position(symbol)
            
        #########################处理开仓逻辑####################################################################
        console.print(f"{time.strftime('%X')} 开始检查{symbol}开仓条件", style="warning")
        try:
            # 获取所有配置项
            configs = get_all_configs()
            open_auto = configs.get('open_auto', 'off').lower() == 'on'
            can_open, reason = check_position_and_orders(api, symbol) #检查当前品种是否有持仓或者未成交委托单
        except Exception as e:
            console.print(f"检查{symbol}开仓条件时出错: {e}", style="error")
            logging.error(f"检查{symbol}开仓条件时出错: {e}")

        if open_auto:
                #出现新K线，或者行情发生变化时
                if can_open: 
                    #新出K线时或行情变化时
                    if api.is_changing(klines.iloc[-1], 'datetime') or api.is_changing(quote, 'last_price'):
                        # 获取配置信息
                        configs = get_all_configs()
                        math_open_lots = configs.get('math_open_lots', 'off').lower() == 'on'
                        
                        # 检查是否需要开多仓 - 金叉条件（当前K线操盘线在空头线上方，前一K线操盘线在空头线下方）
                        if position.pos_long==0 and (dks == "只做多" or dks == "双向") and dks != "只做空" and dks != "不开仓仅止损" and trading_line.iloc[-2] > short_line.iloc[-2] and trading_line.iloc[-3] < short_line.iloc[-3]:
                        # 对上海交易所的商品开多仓
                            if symbol.startswith('SHFE'):
                                limit_price = quote.ask_price1 + 2 * quote.price_tick
                                # 开仓并获取订单ID
                                # 查询数据库中config表的math_open_lots字段
                                math_open_lots = configs.get('math_open_lots', 'off').lower() == 'on'
                                # 先设置默认值，确保volume始终有值
                                volume = 1
                                if math_open_lots:
                                    # 从数据库的products表获取当前品种每手保证金
                                    if USE_MYSQL:
                                        # MySQL连接方式
                                        try:
                                            conn = db.connection()
                                            cursor = conn.cursor()
                                            cursor.execute('SELECT margin FROM products WHERE exchange_code = %s', (symbol,))
                                            product_bond = cursor.fetchone()
                                            if product_bond is None:
                                                product_bond = (1000,)  # 设置默认保证金值
                                        except Exception as e:
                                            logging.error(f"MySQL查询失败: {e}")
                                            product_bond = (1000,)  # 设置默认保证金值
                                        finally:
                                            if 'cursor' in locals():
                                                cursor.close()
                                            if 'conn' in locals():
                                                conn.close()
                                    else:
                                        # SQLite连接方式
                                        try:
                                            conn = sqlite3.connect('trade_monitor.db', check_same_thread=False)
                                            cursor = conn.cursor()
                                            cursor.execute('SELECT margin FROM products WHERE exchange_code = ?', (symbol,))
                                            product_bond = cursor.fetchone()
                                            if product_bond is None:
                                                product_bond = (1000,)  # 设置默认保证金值
                                        except Exception as e:
                                            logging.error(f"SQLite查询失败: {e}")
                                            product_bond = (1000,)  # 设置默认保证金值
                                        finally:
                                            if 'cursor' in locals():
                                                cursor.close()
                                            if 'conn' in locals():
                                                conn.close()
                                    if product_bond and product_bond[0]:
                                        # 获取可用资金
                                        available_funds = api.get_account().available
                                        # 按可用资金20%除以当前品种保证金后取整再除以3计算目标持仓量
                                        target_volume = int(((available_funds * POSITION_FUND_RATIO) / product_bond[0]) / 3)
                                        # 获取已有持仓量
                                        current_position = position.pos_long  # 修正为获取多仓持仓量
                                        # 计算需要开仓的手数
                                        try:
                                            volume = max(1, target_volume - current_position)
                                        except Exception as e:
                                            logging.error(f"计算开仓手数时出错: {e}")
                                            volume = 1  # 设置默认手数
                                    else:
                                        volume = 1
                                print("当前品种开仓手数是：",volume)
                            # 执行开仓操作并注册回调
                            if math.isnan(limit_price):
                                limit_price = quote.last_price
                                logging.warning(f"检测到无效limit_price({limit_price})，已使用最新成交价替代")
                            try:
                                order_id = api.insert_order(
                                    symbol=symbol,
                                    direction="BUY",
                                    offset="OPEN",
                                    volume=volume,
                                    limit_price=limit_price
                                )
                            except Exception as e:
                                logging.error(f"下单失败: {e}")
                                raise
                            console.print(
                                f"{time.strftime('%X')} 开SHFE{symbol}多仓: 手数: {volume}, 订单ID: {order_id}",
                                style="trade"
                            )
                            logging.info(
                                f"开SHFE{symbol}多仓: 手数: {volume}, 开仓价格: {limit_price}, 订单ID: {order_id}"
                            )
                            # 记录委托单到数据库
                            try:
                                insert_trade_orders(
                                    order_id=order_id,
                                    symbol=symbol,
                                    direction="BUY",
                                    offset="OPEN",
                                    volume=volume,
                                    price=limit_price,
                                    status="ALIVE"
                                )
                            except Exception as e:
                                logging.error(f"记录委托单失败: {e}")
                            
                            # 注册订单状态变更回调
                            api.get_order(order_id, lambda o: on_order_status_changed(
                                o, symbol, volume, order_id, limit_price, "BUY", "OPEN", "开多委托"
                            ))
                            
                        else:
                            # 非上海交易所的商品开多仓
                                limit_price = quote.ask_price1 + 2 * quote.price_tick
                                # 查询数据库中config表的math_open_lots字段
                                math_open_lots = configs.get('math_open_lots', 'off').lower() == 'on'
                                # 先设置默认值，确保volume始终有值
                                volume = 1
                                if math_open_lots:
                                    # 从数据库的products表获取当前品种每手保证金
                                    if USE_MYSQL:
                                        # MySQL连接方式
                                        try:
                                            conn = db.connection()
                                            cursor = conn.cursor()
                                            cursor.execute('SELECT margin FROM products WHERE exchange_code = %s', (symbol,))
                                            product_bond = cursor.fetchone()
                                            if product_bond is None:
                                                product_bond = (1000,)  # 设置默认保证金值
                                        except Exception as e:
                                            logging.error(f"MySQL查询失败: {e}")
                                            product_bond = (1000,)  # 设置默认保证金值
                                        finally:
                                            if 'cursor' in locals():
                                                cursor.close()
                                            if 'conn' in locals():
                                                conn.close()
                                    else:
                                        # SQLite连接方式
                                        try:
                                            conn = sqlite3.connect('trade_monitor.db', check_same_thread=False)
                                            cursor = conn.cursor()
                                            cursor.execute('SELECT margin FROM products WHERE exchange_code = ?', (symbol,))
                                            product_bond = cursor.fetchone()
                                            if product_bond is None:
                                                product_bond = (1000,)  # 设置默认保证金值
                                        except Exception as e:
                                            logging.error(f"SQLite查询失败: {e}")
                                            product_bond = (1000,)  # 设置默认保证金值
                                        finally:
                                            if 'cursor' in locals():
                                                cursor.close()
                                            if 'conn' in locals():
                                                conn.close()
                                    if product_bond and product_bond[0]:
                                        # 获取可用资金
                                        available_funds = api.get_account().available
                                        # 按可用资金20%除以当前品种保证金后取整再除以3计算目标持仓量
                                        target_volume = int(((available_funds * POSITION_FUND_RATIO) / product_bond[0]) / 3)
                                        # 获取已有持仓量
                                        current_position = position.pos_long  # 修正为获取多仓持仓量
                                        # 计算需要开仓的手数
                                        try:
                                            volume = max(1, target_volume - current_position)
                                        except Exception as e:
                                            logging.error(f"计算开仓手数时出错: {e}")
                                            volume = 1  # 设置默认手数
                                    else:
                                        volume = 1
                                # 开仓并获取订单ID
                                order = api.insert_order(
                                    symbol=symbol,
                                    direction="BUY",
                                    offset="OPEN",
                                    volume=volume,
                                    limit_price=limit_price
                                )
                                # 兼容不同返回类型，提取字符串订单ID
                                safe_order_id = (order if isinstance(order, str) else getattr(order, 'order_id', None))
                                if isinstance(safe_order_id, int):
                                    safe_order_id = str(safe_order_id)
                                console.print(
                                    f"{time.strftime('%X')} 开{symbol}多仓: 手数: {volume}, 订单ID: {safe_order_id}",
                                    style="trade"
                                )
                                logging.info(
                                    f"开{symbol}多仓: 手数: {volume}, 开仓价格: {limit_price}, 订单ID: {safe_order_id}"
                                )
                                # 记录委托单到数据库
                                try:
                                    insert_trade_orders(
                                        order_id=safe_order_id,
                                        symbol=symbol,
                                        direction="BUY",
                                        offset="OPEN",
                                        volume=volume,
                                        price=limit_price,
                                        status="ALIVE"
                                    )
                                except Exception as e:
                                    logging.error(f"记录委托单失败: {e}")
                                
                                # 注册订单状态变更回调
                                api.get_order(safe_order_id, lambda o: on_order_status_changed(
                                    o, symbol, volume, safe_order_id, limit_price, "BUY", "OPEN", "开多委托"
                                ))
                                    
                               

                        # 检查是否需要开空仓 - 死叉条件（当前K线操盘线在空头线下方，前一K线操盘线在空头线上方）
                        if position.pos_short == 0 and (dks == "只做空" or dks == "双向")  and dks != "只做多" and dks != "不开仓仅止损" and trading_line.iloc[-2] < short_line.iloc[-2] and trading_line.iloc[-3] > short_line.iloc[-3]:
                            # 对上海交易所的商品开空仓
                            if symbol.startswith('SHFE'):
                                limit_price = quote.bid_price1 - 2 * quote.price_tick
                                # 查询数据库中config表的math_open_lots字段
                                math_open_lots = configs.get('math_open_lots', 'off').lower() == 'on'
                                # 先设置默认值，确保volume始终有值
                                volume = 1
                                if math_open_lots:
                                    # 从数据库的products表获取当前品种每手保证金
                                    if USE_MYSQL:
                                        # MySQL连接方式
                                        try:
                                            conn = db.connection()
                                            cursor = conn.cursor()
                                            cursor.execute('SELECT margin FROM products WHERE exchange_code = %s', (symbol,))
                                            product_bond = cursor.fetchone()
                                            if product_bond is None:
                                                product_bond = (1000,)  # 设置默认保证金值
                                        except Exception as e:
                                            logging.error(f"MySQL查询失败: {e}")
                                            product_bond = (1000,)  # 设置默认保证金值
                                        finally:
                                            if 'cursor' in locals():
                                                cursor.close()
                                            if 'conn' in locals():
                                                conn.close()
                                    else:
                                        # SQLite连接方式
                                        try:
                                            conn = sqlite3.connect('trade_monitor.db', check_same_thread=False)
                                            cursor = conn.cursor()
                                            cursor.execute('SELECT margin FROM products WHERE exchange_code = ?', (symbol,))
                                            product_bond = cursor.fetchone()
                                            if product_bond is None:
                                                product_bond = (1000,)  # 设置默认保证金值
                                        except Exception as e:
                                            logging.error(f"SQLite查询失败: {e}")
                                            product_bond = (1000,)  # 设置默认保证金值
                                        finally:
                                            if 'cursor' in locals():
                                                cursor.close()
                                            if 'conn' in locals():
                                                conn.close()
                                    if product_bond and product_bond[0]:
                                        # 获取可用资金
                                        available_funds = api.get_account().available
                                        # 按可用资金20%除以当前品种保证金后取整再除以3计算目标持仓量
                                        target_volume = int(((available_funds * POSITION_FUND_RATIO) / product_bond[0]) / 3)
                                        # 获取已有持仓量
                                        current_position = position.pos_short
                                        # 计算需要开仓的手数
                                        try:
                                            volume = max(1, target_volume - current_position)
                                        except Exception as e:
                                            logging.error(f"计算开仓手数时出错: {e}")
                                            volume = 1  # 设置默认手数
                            # 开仓并获取订单ID
                            if math.isnan(limit_price):
                                limit_price = quote.last_price
                                logging.warning(f"检测到无效limit_price({limit_price})，已使用最新成交价替代")
                            try:
                                order_id = api.insert_order(
                                    symbol=symbol,
                                    direction="SELL",
                                    offset="OPEN",
                                    volume=volume,
                                    limit_price=limit_price
                                )
                            except Exception as e:
                                logging.error(f"下单失败: {e}")
                                raise
                            console.print(
                                f"{time.strftime('%X')} 开SHFE{symbol}空仓: 手数: {volume}, 订单ID: {order_id}",
                                style="trade"
                            )
                            logging.info(
                                f"开SHFE{symbol}空仓: 手数: {volume}, 开仓价格: {limit_price}, 订单ID: {order_id}"
                            )
                            # 记录委托单到数据库
                            try:
                                insert_trade_orders(
                                    order_id=order_id,
                                    symbol=symbol,
                                    direction="SELL",
                                    offset="OPEN",
                                    volume=volume,
                                    price=limit_price,
                                    status="ALIVE"
                                )
                            except Exception as e:
                                logging.error(f"记录委托单失败: {e}")
                        else:
                            # 非上海交易所的商品开空仓
                            limit_price = quote.bid_price1 - 2 * quote.price_tick
                            # 查询数据库中config表的math_open_lots字段
                            math_open_lots = configs.get('math_open_lots', 'off').lower() == 'on'
                            # 先设置默认值，确保volume始终有值
                            volume = 1
                            if math_open_lots:
                                # 从数据库的products表获取当前品种每手保证金
                                if USE_MYSQL:
                                    # MySQL连接方式
                                    try:
                                        conn = db.connection()
                                        cursor = conn.cursor()
                                        cursor.execute('SELECT margin FROM products WHERE exchange_code = %s', (symbol,))
                                        product_bond = cursor.fetchone()
                                        if product_bond is None:
                                            product_bond = (1000,)  # 设置默认保证金值
                                    except Exception as e:
                                        logging.error(f"MySQL查询失败: {e}")
                                        product_bond = (1000,)  # 设置默认保证金值
                                    finally:
                                        if 'cursor' in locals():
                                            cursor.close()
                                        if 'conn' in locals():
                                            conn.close()
                                else:
                                    # SQLite连接方式
                                    try:
                                        conn = sqlite3.connect('trade_monitor.db', check_same_thread=False)
                                        cursor = conn.cursor()
                                        cursor.execute('SELECT margin FROM products WHERE exchange_code = ?', (symbol,))
                                        product_bond = cursor.fetchone()
                                        if product_bond is None:
                                            product_bond = (1000,)  # 设置默认保证金值
                                    except Exception as e:
                                        logging.error(f"SQLite查询失败: {e}")
                                        product_bond = (1000,)  # 设置默认保证金值
                                    finally:
                                        if 'cursor' in locals():
                                            cursor.close()
                                        if 'conn' in locals():
                                            conn.close()
                                if product_bond and product_bond[0]:
                                    # 获取可用资金
                                    available_funds = api.get_account().available
                                    # 按可用资金20%除以当前品种保证金后取整再除以3计算目标持仓量
                                    target_volume = int(((available_funds * POSITION_FUND_RATIO) / product_bond[0]) / 3)
                                    # 获取已有持仓量
                                    current_position = position.pos_short
                                    # 计算需要开仓的手数
                                    try:
                                        volume = max(1, target_volume - current_position)
                                    except Exception as e:
                                        logging.error(f"计算开仓手数时出错: {e}")
                                        volume = 1  # 设置默认手数
                                else:
                                    volume = 1
                            # 开仓并获取订单ID
                            order = api.insert_order(
                                symbol=symbol,
                                direction="SELL",
                                offset="OPEN",
                                volume=volume,
                                limit_price=limit_price
                            )
                            # 兼容不同返回类型，提取字符串订单ID
                            safe_order_id = (order if isinstance(order, str) else getattr(order, 'order_id', None))
                            if isinstance(safe_order_id, int):
                                safe_order_id = str(safe_order_id)
                            console.print(
                                f"{time.strftime('%X')} 开{symbol}空仓: 手数: {volume}, 订单ID: {safe_order_id}",
                                style="trade"
                            )
                            logging.info(
                                f"开{symbol}空仓: 手数: {volume}, 开仓价格: {limit_price}, 订单ID: {safe_order_id}"
                            )
                            # 记录委托单到数据库
                            try:
                                insert_trade_orders(
                                    order_id=safe_order_id,
                                    symbol=symbol,
                                    direction="SELL",
                                    offset="OPEN",
                                    volume=volume,
                                    price=limit_price,
                                    status="ALIVE"
                                )
                            except Exception as e:
                                logging.error(f"记录委托单失败: {e}")
                            
                            # 注册订单状态变更回调
                            api.get_order(safe_order_id, lambda o: on_order_status_changed(
                                o, symbol, volume, safe_order_id, limit_price, "SELL", "OPEN", "开空委托"
                            ))
    

####################################################主函数##############################################
if __name__ == "__main__":
    threads = []
    try:
        # 测试数据库连接
        # try:
        #     conn = db.connection()
        #     cursor = conn.cursor()
        #     cursor.execute("SELECT 1")
        #     result = cursor.fetchone()
        #     cursor.close()
        #     conn.close()
        #     if result and result[0] == 1:
        #         console.print("数据库连接测试成功!", style="success")
        #     else:
        #         console.print("数据库连接测试失败: 无法获取预期结果", style="error")
        #         exit(1)
        # except Exception as e:
        #     console.print(f"数据库连接测试失败: {e}", style="error")
        #     logging.error(f"数据库连接测试失败: {e}", exc_info=True)
        #     exit(1)
            
        # 获取待监控的品种
        symbol_list = get_symbols()
        if not symbol_list:
            console.print("没有找到需要监控的品种，请检查数据库配置", style="warning")
            exit(1)
            
        console.print(f"**********{time.strftime('%X')} 系统开始运行 **********", style="warning")
        console.print(f"监控品种列表: {symbol_list}", style="info")
        
        i=1
        for symbol in symbol_list:
            console.print(f"**********{time.strftime('%X')} {i} ，开始监控 {symbol} **********", style="warning")
            t = Thread(target=stop_loss, args=(symbol,), daemon=True)
            t.start()
            threads.append(t)
            time.sleep(3)
            i=i+1
            
        # 主线程等待所有子线程完成
        while True:
            time.sleep(10)
            
    except KeyboardInterrupt:
        console.print("正在停止所有线程...", style="warning")
        if api is not None:
            api.close()
    except Exception as e:
        console.print(f"主程序出错: {e}", style="error")
        logging.error(f"主程序出错: {e}", exc_info=True)
    finally:
        console.print("程序已停止", style="info")